package com.gzhryc.shared_device.cdb.code;

import com.gzhryc.common.StringTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.cdb.code.dao.db.BatteryCabinet;
import com.gzhryc.shared_device.cdb.code.dao.db.CDBOrder;
import com.gzhryc.shared_device.cdb.code.dao.enums.CDBOrderEnum;
import com.gzhryc.shared_device.cdb.code.services.BatteryCabinetService;
import com.gzhryc.shared_device.cdb.code.services.CDBOrderService;
import com.gzhryc.shared_device.cdb.core.ICDBNetworkService;
import com.gzhryc.shared_device.cdb.core.models.CDBExecuteResult;
import com.gzhryc.shared_device.cdb.core.models.CDBLeaseCommand;
import com.gzhryc.shared_device.cdb.core.protocol.v1.V1_CDBConstants;

public class CDBWorkThread implements Runnable{

    static Logger log = Logger.getLogger(CDBWorkThread.class);

    final String jdbcKey;
    final CDBOrder deviceOrder;
    final ICDBNetworkService networkService;
    final OperateInfo operateInfo;


    public CDBWorkThread(String jdbcKey, CDBOrder deviceOrder, ICDBNetworkService networkService, OperateInfo operateInfo){
        this.jdbcKey = jdbcKey;
        this.deviceOrder = deviceOrder;
        this.networkService = networkService;
        this.operateInfo = operateInfo;
    }

    @Override
    public void run() {
        log.info("共享充电宝工作线程，执行订单：{{0}}，数据库Key：{{1}}", deviceOrder.getTradeNo(), jdbcKey);
        try {
            MultiDBTools.setJdbcKey(jdbcKey);
            BatteryCabinet batteryCabinet = BatteryCabinetService.self().getByDeviceSn(deviceOrder.getLeaseChargingCabinetSn());
            if (batteryCabinet != null) {
                if (networkService != null) {
                    //设置工作缓存，用于IOT回调时根据消息ID获取订单信息
                    String msgId = V1_CDBConstants.getMessageId();
                    CDBWorkCacheManager.DeviceWorkInfo deviceWorkInfo = new CDBWorkCacheManager.DeviceWorkInfo();
                    deviceWorkInfo.setDeviceSn(deviceOrder.getLeaseChargingCabinetSn());
                    deviceWorkInfo.setSlotNum(deviceOrder.getLeaseSlotNum());
                    deviceWorkInfo.setTradeNo(deviceOrder.getTradeNo());
                    if (!CDBWorkCacheManager.self().setData(msgId, deviceWorkInfo)) {
                        log.error("共享充电宝工作线程，缓存设备工作信息失败，msgId = {{0}}，信息：{{1:json}}", msgId, deviceWorkInfo);
                    }
                    if (CDBOrderService.self(deviceOrder.getCreateDate()).waitStartToOpening(deviceOrder.getTradeNo())) {
                        Integer leaseErrorState = CDBOrderEnum.LeaseErrorState.Normal.index();
                        try {
                            CDBLeaseCommand command = new CDBLeaseCommand();
                            command.setMessageId(msgId);
                            command.setDeviceSn(deviceOrder.getLeaseChargingCabinetSn());
                            command.setSlotNum(deviceOrder.getLeaseSlotNum());
                            command.setTradeNo(deviceOrder.getTradeNo());

                            CDBExecuteResult executeResult = networkService.lease(command);
                            if (executeResult != null) {
                                if (CDBExecuteResult.TIMEOUT.equals(executeResult.getCode())) {
                                    leaseErrorState = CDBOrderEnum.LeaseErrorState.Timeout.index();
                                    operateInfo.setOperateNote("发送租借命令超时");
                                }else if (CDBExecuteResult.FAIL.equals(executeResult.getCode())) {
                                    //不进行记录错误，有IOT回调记录
                                    if (StringTools.isNotBlank(executeResult.getMsg())) {
                                        log.error("发送命令失败，返回错误：{{0}}，订单：{{1}}", executeResult.getMsg(), deviceOrder.getTradeNo());
                                    } else {
                                        log.error("发送命令失败，订单：{{0}}", deviceOrder.getTradeNo());
                                    }
                                }
                            } else {
                                leaseErrorState = CDBOrderEnum.LeaseErrorState.Timeout.index();
                                operateInfo.setOperateNote("发送租借命令超时，无返回");
                                log.error("共享充电宝网络服务无响应，订单：{{0}}", deviceOrder.getTradeNo());
                            }
                        } catch (Exception e) {
                            log.error(e.getMessage(), e);
                        } finally {
                            if (CDBOrderEnum.LeaseErrorState.Timeout.index().equals(leaseErrorState)) {
                                log.error("共享充电宝订单{{0}}开启失败，启动自动退款功能", deviceOrder.getTradeNo());
                                CDBOrderService.self(deviceOrder.getCreateDate()).openingFail(deviceOrder, leaseErrorState,operateInfo);
                            }
                        }
                    } else {
                        log.error("共享充电宝订单{{0}}从等待开始->开启中修改失败", deviceOrder.getTradeNo());
                    }
                } else {
                    log.error("未找到共享充电宝设备网络服务，IOT节点：{{0}}，设备序列号：{{1}}，订单号：{{2}}", batteryCabinet.getIotNodeId()
                            , batteryCabinet.getDeviceSn(), deviceOrder.getTradeNo());
                }
            } else {
                log.error("未找到共享充电宝设备{{0}}，订单号：{{1}}", deviceOrder.getLeaseChargingCabinetSn(), deviceOrder.getTradeNo());
            }
        } finally {
            JdbcSession.clear();
            MultiDBTools.removeJdbcKey();
        }
    }
}
